﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using Microsoft.Office.Interop.Excel;

namespace WFL.Office.Excel
{
    public class RangeIndex
    {
        public ExcelRange this[object cell1, object cell2 = null]
        {
            get { return _range(cell1, cell2); }
        }

        public ExcelRange this[int[] index1, int[] index2 = null]
        {
            get 
            {
                object cell1 = IndexToSerial(index1);
                object cell2 = index2 != null ? IndexToSerial(index2) : Type.Missing;
                return _range(cell1, cell2); 
            }
        }

        internal delegate ExcelRange RangeCallback(object cell1, object cell2);

        private RangeCallback _range;

        internal RangeIndex(RangeCallback range)
        {
            _range = range;
        }

        private string IndexToSerial(int[] index)
        {
            if (index == null
                || index.Length != 2)
            {
                throw new ArgumentException();
            }
            int rowIndex = index[0];
            int columnIndex = index[1];
            if (rowIndex < 1
                || columnIndex < 1)
            {
                throw new ArgumentOutOfRangeException();
            }
            IList<char> list = new List<char>();
            int remainder = 0;
            int quotient = columnIndex;
            while (quotient > 0)
            {
                quotient = Math.DivRem(quotient, 26, out remainder);
                if (remainder == 0)
                {
                    list.Add('Z');
                    quotient -= 1;
                }
                else
                {
                    list.Add((char)(64 + remainder));
                }
            }
            int count = list.Count;
            char[] column = new char[count];
            for (int i = 0; i <count; i++)
            {
                column[i] = list[count - 1 - i];
            }
            return new string(column) + rowIndex.ToString();
        }

        private int[] SerialToIndex(string cell)
        {
            Match match = Regex.Match(cell, @"^([A-Z]+)([1-9]\d*)$", RegexOptions.IgnoreCase);
            if (!match.Success)
            {
                throw new ArgumentException();
            }
            int[] index = new int[2];
            int rowIndex = Convert.ToInt32(match.Groups[2].Captures[0].Value);
            string columnStr = match.Groups[1].Captures[0].Value;
            //转换列字母索引为数字索引
            int columnIndex = 0;
            int length = columnStr.Length - 1;
            for (int i = length; i >= 0; i--)
            {
                columnIndex += (int)Math.Pow(26, length - i) * ((int)columnStr[i] - 64);
            }
            index[0] = rowIndex;
            index[1] = columnIndex;
            return index;
        }
    }
}
